(*$R-*)
(*WHETSTONE BENCHMARK - - DIRECT TRANSLITERATION OF THE ORIGINAL 
                          ALGOL PROGRAM FROM:
    "A SYNTHETIC BENCKMARK"  BY H. J. CURNOW & B. A. WICHMANN
    'THE COMPUTER JOURNAL' VOL 19, NO. *)

(*$G+*)   (* TURN ON 'GOTO' -- FOR UCSD COMPILER                     *)
          (* UGLY, BUT THAT'S THE WAY IT WAS IN THE ORIGINAL VERSION *) 
PROGRAM WHETSTONE;

CONST T=0.499975;
      T1=0.50025;
      T2=2.0;

TYPE ARGARRAY = ARRAY[1..4] OF REAL;

VAR E1 : ARRAY[1..4] OF REAL;
    X,Y,Z,X1,X2,X3,X4 : REAL;
    MODULE,I,J,K,L,N1,N2,N3,N4,N5,N6,N7,N8,N9,N10,N11 : INTEGER;

PROCEDURE PA(VAR E:ARGARRAY);

LABEL 1;
VAR J : INTEGER;

BEGIN
   J:=0;

1:
   E[1]:=(E[1]+E[2]+E[3]-E[4])*T;
   E[2]:=(E[1]+E[2]-E[3]+E[4])*T;
   E[3]:=(E[1]-E[2]+E[3]+E[4])*T;
   E[4]:=(-E[1]+E[2]+E[3]+E[4])/T2;
   J:=J+1;
   IF J<6 THEN
    GOTO 1
END;  (* PROCEDURE PA*)


PROCEDURE P0;

BEGIN
   E1[J]:=E1[K];
   E1[K]:=E1[L];
   E1[L]:=E1[J]
END;   (* PROCEDURE P0 *)

PROCEDURE P3(X,Y:REAL;VAR Z:REAL);

BEGIN
   X:=T*(X+Y);
   Y:=T*(X+Y);
   Z:=(X+Y)/T2
END;  (* PROCEDURE P3 *)

PROCEDURE MODULE1; (* MODULE 1: SIMPLE IDENTIFIERS *)

BEGIN
  X1:=1.0;
  X2:=-1.0; X3:=-1.0; X4:=-1.0;

  FOR I:=1 TO N1 DO
  BEGIN
    X1:=(X1+X2+X3-X4)*T;
    X2:=(X1+X2-X3+X4)*T;
    X3:=(X1-X2+X3+X4)*T;
    X4:=(-X1+X2+X3+X4)*T
  END;

END; (* MODULE 1 *)

PROCEDURE MODULE2; (* MODULE 2: ARRAY ELEMENTS *)

BEGIN
E1[1]:=1.0;
E1[2]:=-1.0; E1[3]:=-1.0; E1[4]:=-1.0;

FOR I:=1 TO N2 DO
  BEGIN
  E1[1]:=(E1[1]+E1[2]+E1[3]-E1[4])*T;
  E1[2]:=(E1[1]+E1[2]-E1[3]+E1[4])*T;
  E1[3]:=(E1[1]-E1[2]+E1[3]+E1[4])*T;
  E1[4]:=(-E1[1]+E1[2]+E1[3]+E1[4])*T
  END;
END;  (* MODULE 2 *)

PROCEDURE MODULE4; (* MODULE 4: CONDITIONAL JUMPS *)

BEGIN
J:=1;
FOR I:=1 TO N4 DO
  BEGIN
    IF J=1 THEN
      J:=2
    ELSE
      J:=3;
    IF J>1 THEN
      J:=0
    ELSE
      J:=1;
    IF J<2 THEN
      J:=1
    ELSE
      J:=0
  END;
END; (* MODULE 4 *)

PROCEDURE MODULE6; (* INTEGER ARITHMETIC *)

BEGIN
  J:=1;
  K:=2;
  L:=3;

  FOR I:= 1 TO N6 DO
  BEGIN
    J:=J*(K-J)*(L-K);
    K:=L*K-(L-J)*K;
    L:=(L-K)*K+J;
    E1[L-1]:=J+K+L;
    E1[K-1]:=J*K*L
  END;
END; (* MODULE 6 *)

PROCEDURE MODULE7; (* MODULE 7: TRIG FUNCTIONS *)

VAR TEMP : REAL;

BEGIN
X:=0.5; Y:=0.5;
FOR I:=1 TO N7 DO
  BEGIN
    TEMP:=COS(X+Y)+COS(X-Y)-1.0;
    X:=T*ATAN(T2*SIN(X)*COS(X)/TEMP);  (*USE ARCTAN FORM OMSI*)
    TEMP:=COS(X+Y)+COS(X-Y)-1.0;
    Y:=T*ATAN(T2*SIN(Y)*COS(Y)/TEMP);
  END;
END; (* MODULE 7 *)

PROCEDURE MODULE8; (* MODULE 8: PROCEDURE CALLS *)

BEGIN
  X:=1.0; Y:=1.0; Z:=1.0;

  FOR I:=1 TO N8 DO
    P3(X,Y,Z)
END; (* MODULE 8 *)

PROCEDURE MODULE10; (* MODULE 10: INTEGER ARTIHMETIC *)

BEGIN
  J:=2;
  K:=3;
  FOR I:=1 TO N10 DO
    BEGIN
    J:=J+K;
    K:=J+K;
    J:=K-J;
    K:=K-J-J
  END;
END; (* MODULE 10 *)

PROCEDURE MODULE11; (* MODULE 11: STANDARD FUNCTIONS *)

BEGIN
  X:=0.75;

  FOR I:=1 TO N11 DO
    X:=SQRT(EXP(LN(X)/T1));
END; (* MODULE 11 *)

PROCEDURE POUT(VAR N,J,K:INTEGER; VAR X1,X2,X3,X4:REAL);

BEGIN
  WRITE('MODULE ',MODULE:2,N:5,J:5,K:5);
  WRITELN(X1:12:3,X2:12:3,X3:12:3,X4:12:3);
END;   (* PROCEDURE POUT *)

BEGIN  (* START WHETSTONE *)

(* READ VALUE OF I, CONTROLLING TOTAL WEIGHT: IF I=10,
    THE TOTAL WEIGHT IS ONE MILLION WHETSTONE INSTRUCTIONS *);

  WRITELN;
  WRITE ('WEIGHTING FACTOR I = '); READLN(I);
  WRITELN;
  N1:=0;
  N2:=12*I;
  N3:=14*I;
  N4:=345*I;
  N5:=0;
  N6:=210*I;
  N7:=32*I;
  N8:=899*I;
  N9:=616*I;
  N10:=0;
  N11:=93*I;

(* MODULAR PROGRAMMING IS USED TO REDUCE THE LENGTH OF MAIN CODE *)

MODULE1; (* SIMPLE IDENTIFIERS *)
MODULE:=1;
POUT(N1,N1,N1,X1,X2,X3,X4);

MODULE2; (* ARRAY ELEMENTS *)
MODULE:=2;
POUT(N2,N3,N2,E1[1],E1[2],E1[3],E1[4]);

(* MODULE 3: ARRAY AS A PARAMETER *)

FOR I:= 1 TO N3 DO

  PA(E1);
MODULE:=3;
POUT(N3,N2,N2,E1[1],E1[2],E1[3],E1[4]);

(* END OF MODULE 3 *)

MODULE4; (* CONDITIONAL JUMPS *)
MODULE:=4;
POUT(N4,J,J,X1,X2,X3,X4);

WRITELN('MODULE  5 OMITTED ');
MODULE6; (* INTEGER ARITHMETIC *)
MODULE:=6;
POUT(N6,J,K,E1[1],E1[2],E1[3],E1[4]);

MODULE7; (* TRIG FUNCTIONS *)
MODULE:=7;
POUT(N7,J,K,X,X,Y,Y);

MODULE8; (* PROCEDURE CALLS *)
MODULE:=8;
POUT(N8,J,K,X,Y,Z,Z);

(* MODULE 9: ARRAY REFERENCES *)

  J:=1;
  K:=2;
  L:=3;
  E1[1]:=1.0;
  E1[2]:=2.0;
  E1[3]:=3.0;

  FOR I:=1 TO N9 DO P0;

MODULE:=9;
POUT(N9,J,K,E1[1],E1[2],E1[3],E1[4]);

MODULE10; (* INTEGER ARITHMETIC *)
MODULE:=10;
POUT(N10,J,K,X1,X2,X3,X4);

MODULE11; (* STANDARD FUNCTIONS *)
MODULE:=11;
POUT(N11,J,K,X,X,X,X);

WRITELN('END OF WHETSTONE')
END. (* END WHETSTONE *)




